﻿using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 依赖属性
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        // Set_MyText 方法用于设置 MyText 属性的值
        private void Set_MyText_Click(object sender, RoutedEventArgs e)
        {
            // 设置 MyText 属性的值为 "Hello, Dependency Property!"
            MyControlInstance.MyText = "Hello, Dependency Property!";
        }

        // Set_Age_Click 方法用于设置 Age 属性的值
        private void Set_Age_Click(object sender, RoutedEventArgs e)
        {
            // 设置 Age 属性的值为 25
            MyControlInstance.Age = 124;
        }
    }

    public class MyControl : TextBox
    {
        // 注册依赖属性（静态字段）
        public static readonly DependencyProperty MyTextProperty =
            DependencyProperty.Register(
                "MyText",             // 属性名称
                typeof(string),            // 属性类型
                typeof(MyControl),         // 所属类型（拥有该属性的类）
                new PropertyMetadata("hello world",   // 默认值
                    OnMyTextChanged),       // 属性变更时的回调
                new ValidateValueCallback(OnValidateValue) // 验证值的回调函数
            );


        public static readonly DependencyProperty AgeProperty =
            DependencyProperty.Register(
                "Age",             // 属性名称
                typeof(int),            // 属性类型
                typeof(MyControl),         // 所属类型（拥有该属性的类）
                new PropertyMetadata(0,   // 默认值
                OnAgeChanged),       // 属性变更时的回调
                // new PropertyMetadata(0,   // 默认值
                //     OnAgeChanged ,// 属性变更时的回调
                //     OnAgeError),  // 强制验证错误回调函数
                new ValidateValueCallback(OnAgeValidate) // 验证值的回调函数
            );


        /// <summary>
        /// 强制验证错误回调函数
        /// </summary>
        /// <param name="d"></param>
        /// <param name="baseValue"></param>
        /// <returns></returns>
        private static object OnAgeError(DependencyObject d, object baseValue)
        {
            int age = (int)baseValue;
            // 如果年龄不在合理范围内，返回默认值 0
            if (age < 0 || age > 120)
            {
                // MessageBox.Show($"Invalid age value: {age}. Setting to default value 0.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return 0; // 返回默认值
            }
            else
            {
                return baseValue; // 如果验证失败，返回默认值 0
            }
        }

        private static bool OnAgeValidate(object value)
        {
            // 验证年龄值是否在合理范围内（例如：0-120岁）
            // return value is int age && age >= 0 && age <= 120;
            return true;
        }

        private static void OnAgeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyControl control)
            {
                // 显示旧的值和新的值
                int oldValue = (int)e.OldValue;
                int newValue = (int)e.NewValue;

                // MessageBox.Show($"Age changed from '{oldValue}' to '{newValue}'", "Property Changed", MessageBoxButton.OK, MessageBoxImage.Information);

                control.Text = $"Age: {newValue}"; // 更新控件的文本内容
            }
        }

        private static bool OnValidateValue(object value)
        {
            // 验证值是否符合要求，这里简单示例为非空字符串
            // return (bool)value;

            // 实际应用中可以添加更复杂的验证逻辑
            // 例如：
            return !string.IsNullOrEmpty(value as string);
            // throw new NotImplementedException();
        }

        // CLR 包装属性（用于访问依赖属性）
        public string MyText
        {
            get => (string)GetValue(MyTextProperty);
            set => SetValue(MyTextProperty, value);
        }

        public int Age
        {
            get => (int)GetValue(AgeProperty);
            set => SetValue(AgeProperty, value);
        }

        // 属性变更回调（当值变化时触发）
        private static void OnMyTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is MyControl control)
            {
                // 显示旧的值和新的值
                string oldValue = e.OldValue as string ?? "null";
                string newValue = e.NewValue as string ?? "null";
                // MessageBox.Show($"MyText changed from '{oldValue}' to '{newValue}'", "Property Changed", MessageBoxButton.OK, MessageBoxImage.Information);

                // 更新控件的文本内容
                control.Text = newValue;
            }
        }
    }
}